package org.song.listprocess;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.song.listprocess.exception.InitJKVListException;

public class JKVList{
	
	JList keyList,valList;
	public JKVList(){
		keyList = new JList();
		valList = new JList();
	}
	/**
	 * construct an JKVList object by even of inputs
	 * @param element JKVList element by key-value pair
	 * @throws InitJKVListException if input argument number isn't even 
	 */
	public JKVList(Object... element) throws InitJKVListException{
		if(element.length%2==1){
			throw new InitJKVListException();
		}
		keyList = new JList();
		valList = new JList();
		
		int len = element.length/2;
		for(int i=0;i<len;i++){
			Object key = element[i*2];
			Object val = element[i*2+1];
			push(key,val);
		}
	}
	

	
	/**
	 * replace key and value list by given input
	 * @param key key list
	 * @param val value list
	 */
	public void replace(JList key,JList val){
		keyList = key;
		valList = val;
	}
	
	/**
	 * push new date,if key exist override value
	 * @param key
	 * @param val
	 */
	public void push(Object key,Object val){
		int n = keyList.findFirst(key);
		if(n==-1){
			keyList.push(key);
			valList.push(val);
		}else{
			valList.change(n, val);
		}
	}
	
	/**
	 * remove key-value pair
	 * @param key
	 */
	public void removeKey(Object key){
		int n = keyList.findFirst(key);
		if(n!=-1){
			keyList.delete(n);
			valList.delete(n);
		}
	}
	
	/**
	 * check value corresponding to key
	 * @param key
	 * @return value
	 */
	public Object value(Object key){
		int n = keyList.findFirst(key);
		if(n==-1)return null;
		else return valList.nth(n);
	}
	
	/**
	 * check if this list matching all key-value pair
	 * @return true if matching else return false
	 */
	public boolean select(Object... kvs){
		int len = kvs.length;
		if(len%2==1)return false;
		len = len/2;
		for(int i=0;i<len;i++){
			Object key = kvs[i*2];
			Object val = kvs[i*2+1];
			int n = keyList.findFirst(key);
			if(n==-1)return false;
			if(!valList.nth(n).equals(val))return false;
		}
		return true;
	}
	
	/**
	 * package list to file
	 * @param filename file name
	 * @return true if package success
	 */
	public boolean packToFile(String filename){
		File file = new File(filename);
		try {
			if(file.exists()){//override file
				file.delete();
				file.createNewFile();
			}
			FileOutputStream os = new FileOutputStream(file);
			os.write(toString().getBytes("UTF-8"));//toString is pack list function
			os.close();
			return true;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		
	}

	/**
	 * read list from file 
	 * @param filename file name
	 */
	public void readFromFile(String filename){
		JList kvList = JList.readFromFile(filename);
		//separate key-value list to keyList and valList
		readFromList(kvList);
	}
	
	public void readFromString(String str){
		JList kvList = JList.readFromString(str);
		readFromList(kvList);
	}
	
	public void readFromList(JList list){
		keyList = (JList)list.first();
		valList = (JList)list.last();
	}
	
	
	
	public JHashList toHashList(){
		JList keyIter = keyList;
		JList valIter = valList;
		JHashList hashList = new JHashList();
		while(keyIter!=null&&valIter!=null){
			hashList.put(keyIter.first(), valIter.first());
			keyIter = keyIter.rest();
			valIter = valIter.rest();
		}
		return hashList;
	}
	/**
	 * pack list to string, group keyList and valList to one list
	 */
	public String toString(){
		return new JList(keyList,valList).toString();
	}
}
